package com.clothing.customization.service.impl;

import com.clothing.customization.dto.ScheduleDTO;
import com.clothing.customization.dto.ScheduleQueryDTO;
import com.clothing.customization.entity.Schedule;
import com.clothing.customization.repository.ScheduleRepository;
import com.clothing.customization.service.ScheduleService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;

@Service
@RequiredArgsConstructor
public class ScheduleServiceImpl implements ScheduleService {

    private final ScheduleRepository scheduleRepository;

    @Override
    public Page<ScheduleDTO> getScheduleList(ScheduleQueryDTO queryDTO) {
        Specification<Schedule> specification = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            if (queryDTO.getTitle() != null && !queryDTO.getTitle().isEmpty()) {
                predicates.add(cb.like(root.get("title"), "%" + queryDTO.getTitle() + "%"));
            }
            
            if (queryDTO.getType() != null && !queryDTO.getType().isEmpty()) {
                predicates.add(cb.equal(root.get("type"), queryDTO.getType()));
            }
            
            if (queryDTO.getPriority() != null && !queryDTO.getPriority().isEmpty()) {
                predicates.add(cb.equal(root.get("priority"), queryDTO.getPriority()));
            }
            
            if (queryDTO.getStatus() != null && !queryDTO.getStatus().isEmpty()) {
                predicates.add(cb.equal(root.get("status"), queryDTO.getStatus()));
            }
            
            if (queryDTO.getStartTime() != null) {
                predicates.add(cb.greaterThanOrEqualTo(root.get("startTime"), queryDTO.getStartTime()));
            }
            
            if (queryDTO.getEndTime() != null) {
                predicates.add(cb.lessThanOrEqualTo(root.get("endTime"), queryDTO.getEndTime()));
            }
            
            return cb.and(predicates.toArray(new Predicate[0]));
        };
        
        Pageable pageable = PageRequest.of(queryDTO.getPageNum() - 1, queryDTO.getPageSize());
        Page<Schedule> schedulePage = scheduleRepository.findAll(specification, pageable);
        
        return schedulePage.map(this::convertToDTO);
    }

    @Override
    public ScheduleDTO getScheduleDetail(Long id) {
        Schedule schedule = scheduleRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("日程不存在"));
        return convertToDTO(schedule);
    }

    @Override
    @Transactional
    public ScheduleDTO createSchedule(ScheduleDTO scheduleDTO) {
        Schedule schedule = new Schedule();
        BeanUtils.copyProperties(scheduleDTO, schedule);
        schedule = scheduleRepository.save(schedule);
        return convertToDTO(schedule);
    }

    @Override
    @Transactional
    public ScheduleDTO updateSchedule(Long id, ScheduleDTO scheduleDTO) {
        Schedule schedule = scheduleRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("日程不存在"));
        
        BeanUtils.copyProperties(scheduleDTO, schedule, "id", "createTime", "updateTime");
        schedule = scheduleRepository.save(schedule);
        return convertToDTO(schedule);
    }

    @Override
    @Transactional
    public void deleteSchedule(Long id) {
        scheduleRepository.deleteById(id);
    }

    @Override
    @Transactional
    public void updateScheduleStatus(Long id, String status) {
        Schedule schedule = scheduleRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("日程不存在"));
        schedule.setStatus(status);
        scheduleRepository.save(schedule);
    }

    private ScheduleDTO convertToDTO(Schedule schedule) {
        ScheduleDTO dto = new ScheduleDTO();
        BeanUtils.copyProperties(schedule, dto);
        return dto;
    }
} 